package com.heatup.apt.common.util.Netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

/**
 * EchoServer
 * <p>
 * 所有 Netty 服务器都需要下面这些：
 * 一个服务器 handler：这个组件实现了服务器的业务逻辑，决定了连接创建后和接收到信息后该如何处理
 * Bootstrapping： 这个是配置服务器的启动代码。最少需要设置服务器绑定的端口，用来监听连接请求。
 * <p>
 * 通过 ChannelHandler 来实现服务器的逻辑
 * <p>
 * Echo Server 将会将接受到的数据的拷贝发送给客户端。
 * 因此，我们需要实现 ChannelInboundHandler 接口，用来定义处理入站事件的方法。
 * 由于我们的应用很简单，只需要继承 ChannelInboundHandlerAdapter 就行了。
 * 这个类 提供了默认 ChannelInboundHandler 的实现，所以只需要覆盖下面的方法：
 * <p>
 * channelRead() - 每个信息入站都会调用
 * channelReadComplete() - 通知处理器最后的 channelRead() 是当前批处理中的最后一条消息时调用
 * exceptionCaught()- 读操作时捕获到异常时调用
 * <p>
 * <p>
 * Created by blank on 2017/11/6 下午2:27
 */
@ChannelHandler.Sharable // 此注解 标识这类的实例之间可以在 channel 里面共享
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        super.channelRead(ctx, msg);
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8));//日志消息输出到控制台
        ctx.write(in);//将所接收的消息返回给发送者. 注意,这里还没有冲刷数据
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//        super.channelReadComplete(ctx);
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER);//冲刷所有待审消息到远程节点.关闭通道后,操作完成
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        super.exceptionCaught(ctx, cause);
        cause.printStackTrace();//打印日志堆栈跟踪
        ctx.close();//关闭通道
    }


}
